﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Game
{
    enum SlimesCategory { PAWN, ARCHER, KNIGHT };
    class Player
    {
        const int SlimesCategorySIZE = 3;
        string _name;
        char _side;
        int[] _eachCount;
        List<Slime> _slimes;
        public int Side
        {
            get { if(char.IsLower(_side)){ return 0;}else{return 1;}; }
        }
        public int SmallConut
        {
            get
            {
                int ret = 0;
                for (int i = 0; i < SlimesCategorySIZE; i++)
                {
                    ret += _eachCount[i];
                }
                return ret;
            }
        }
        public Player(char side, int x, int y, string name)
        {
            _slimes = new List<Slime>();
            _side = side;
            _slimes.Add(new Mother(_side, 0, x, y));
            _slimes.Add(new Pawn(_side, 1, x + 1, y - 1));
            _slimes.Add(new Pawn(_side, 2, x - 1, y + 1));
            _slimes.Add(new Pawn(_side, 3, x + 1, y + 1));
            _slimes.Add(new Pawn(_side, 4, x - 1, y - 1));
            _slimes.Add(new Archer(_side, 5, x , y - 1));
            _slimes.Add(new Archer(_side, 6, x, y + 1));
            _name = name;
            _eachCount = new int[SlimesCategorySIZE];
            _eachCount[(int)SlimesCategory.PAWN] = 4;
            _eachCount[(int)SlimesCategory.ARCHER] = 2;

        }
        public Player(Player other)
        {
            this._name = other._name;
            this._side = other._side;
            this._eachCount = other._eachCount;
            this._slimes = new  List<Slime>();
            for(int i =0;i<other._slimes.Count;i++){
                Slime tempS = other._slimes[i].Clone();
                this._slimes.Add(tempS);
            } 

        }
        public List<Slime> Slimes {
            get { return _slimes; }
        }

        public void Display(char C)
        {

            Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
            Console.Write(_name + "    "); _slimes[0].Display(C); Console.Write("\n");
            for (int i = 1; i < _slimes.Count; i++)
            {
                _slimes[i].Display(C);
                if (i % 3 == 0) Console.Write("\n");
            }
            Console.WriteLine("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        }

        public void Turn()
        {
            foreach (var slime in _slimes)
            {
                slime.WakeUp();
            }
        }

        public void TurnOff()
        {
            foreach (var slime in _slimes)
            {
                slime.Hited = false;
            }
        }

        private void Born(char ID, int x, int y)
        {
            if (_slimes.Count >=10)
            {
                Console.WriteLine("你已經有太多小史萊姆了");
               // Console.Read();
                //do nothing
            }
            else if (Math.Abs(x - _slimes[0].X) + Math.Abs(y - _slimes[0].Y) > 1)
            {
                Console.WriteLine("只能生在大史萊姆周圍四格");
                //Console.Read();
                //do nothing
            }
            else if (_slimes[0].Hited)
            {
                Console.WriteLine("被攻擊過不能生小史萊姆");
                //Console.Read();
                //do nothing
            }
            else if (!_slimes[0].Active)
            {
                Console.WriteLine("攻擊或生產過不能生小史萊姆");
                //Console.Read();
                //do nothing
            }
            else if (ID == 'A' || ID == 'a')
            { // 弓手
                int Sid = 0; 
                while (IsExistence(Sid)) {++Sid;}
                Slime temp = new Archer(_side, Sid, x, y);
                if (_slimes[0].HP - temp .Cost > 0)
                {
                    _slimes.Add(temp);
                    _slimes[0].HP -= _slimes[_slimes.Count - 1].Cost;
                    _slimes[0].Active = false;
                    _eachCount[(int)SlimesCategory.ARCHER]++;
                } 

            }
            else if (ID == 'K' || ID == 'k')    // 騎士
            {
                int Sid = 0;
                while (IsExistence(Sid)) { ++Sid; }
                Slime temp = new Knight(_side, Sid, x, y);
                if (_slimes[0].HP - temp.Cost > 0)
                {
                    _slimes.Add(temp);
                    _slimes[0].HP -= _slimes[_slimes.Count - 1].Cost;
                    _slimes[0].Active = false;
                    _eachCount[(int)SlimesCategory.ARCHER]++;
                } 
            }
            else if (ID == 'P' || ID == 'p')   // 小兵
            {
                int Sid = 0;
                while (IsExistence(Sid)) { ++Sid; }
                Slime temp = new Pawn(_side, Sid, x, y);
                if (_slimes[0].HP - temp.Cost > 0)
                {
                    _slimes.Add(temp);
                    _slimes[0].HP -= _slimes[_slimes.Count - 1].Cost;
                    _slimes[0].Active = false;
                    _eachCount[(int)SlimesCategory.ARCHER]++;
                } 
            }

        }

        public void Born(char ID, Position P)
        {
            Born(ID, P.X, P.Y);
        }
        public int Closest(Position P)
        {
            int ret = 0;
            int min = 999999;
            for (int i = 0; i < _slimes.Count; i++)
            {
                if (_slimes[i].HP <= 0) {
                    continue;
                }
                int temp = Math.Abs(P.X - _slimes[i].X) + Math.Abs(P.Y - _slimes[i].Y);
                if (temp < min)
                {
                    min = temp;
                    ret = i;
                }

            }
            return ret;
        }
        public int EachCount(SlimesCategory index)
        {
            return _eachCount[(int)index];
        }
        public void Update()
        {

            for (int i = 1; i < _slimes.Count; i++)
            {

                if (_slimes[i].IsDead()) {
                    _slimes.RemoveAt(i);
                    --i;
                }
            }
        }
        public Slime getID(char name) { 
            for (int i =0 ;i < _slimes.Count ; i ++  ){
                if (_slimes[i].Icon == name) {
                    return _slimes[i];
                }
            }
            //例外
            return _slimes[-1];
        }
        public Slime getSlime(int id)
        {
            for (int i = 0; i < _slimes.Count; i++)
            {
                if (_slimes[i].ID == id)
                {
                    return _slimes[i];
                }
            }
            //例外
            return _slimes[-1];
        }
        
        public bool IsExistence(char name)
        {
            for (int i = 0; i < _slimes.Count; i++)
            {
                if (_slimes[i].Icon == name)
                {
                    return true;
                }
            }
            return false;
        }
        public bool IsExistence(int id)
        {
            for (int i = 0; i < _slimes.Count; i++)
            {
                if (_slimes[i].ID == id)
                {
                    return true;
                }
            }
            return false;
        }
        public List<Slime> CopySlimes()
        {
            List<Slime> ret = new List<Slime>();
            for (int i = 0; i < _slimes.Count; i++)
            {
                ret.Add(_slimes[i].Clone());
            }
            return ret;
        }

    }
}
